package com.weixin.engine.daily.statemachine.machine;

import com.google.common.collect.HashBasedTable;
import com.weixin.engine.daily.statemachine.enums.Event;
import com.weixin.engine.daily.statemachine.enums.State;
import com.weixin.engine.daily.statemachine.handler.IStateHandler;
import com.weixin.engine.daily.statemachine.pojo.SopProcess;
import lombok.Data;

import java.util.List;

/**
 * 抽象状态机
 */
public abstract class AbstractStateMachine {

    /**
     * 执行类
     */
    @Data
    static class SopExec {
        private State nextState;
        private IStateHandler stateHandler;
    }

    private HashBasedTable<State, Event, AbstractStateMachine.SopExec> hashBasedTable = HashBasedTable.create();

    /**
     * 数据初始化
     */ {
        List<SopProcess> sopProcesses = init();
        sopProcesses.forEach(item -> {
            AbstractStateMachine.SopExec sopExec = new AbstractStateMachine.SopExec();
            sopExec.setNextState(item.getTo());
            sopExec.setStateHandler(item.getHandler());
            hashBasedTable.put(item.getFrom(), item.getEvent(), sopExec);
        });
    }

    abstract List<SopProcess> init();

    /**
     * 获取下一个状态
     *
     * @param from  初始状态
     * @param event 事件
     * @return 下一个状态
     */
    public State getNext(State from, Event event) {
        AbstractStateMachine.SopExec sopExec = hashBasedTable.get(from, event);
        if (sopExec == null) {
            throw new RuntimeException("状态错误");
        }
        return sopExec.getNextState();
    }

    /**
     * 获取下一个处理器
     *
     * @param from  初始状态
     * @param event 事件
     * @return 下一个处理器
     */
    public IStateHandler getHandle(State from, Event event) {
        AbstractStateMachine.SopExec sopExec = hashBasedTable.get(from, event);
        if (sopExec == null) {
            throw new RuntimeException("状态错误");
        }
        return sopExec.getStateHandler();
    }
}
